package com.bigflexlib.ds.container.impl
{
	
	import flash.utils.Dictionary;
	
	import com.bigflexlib.core.comparison.result.ComparisonResult;
	import com.bigflexlib.ds.container.IRWContainer;
	import com.bigflexlib.ds.container.utils.ContainerUtil;
	import com.bigflexlib.utils.AutoUpdateFlag;

	/**
	 * 
	 * 
	 * @author aldo.bucchi@gmail.com
	 * 
	 */
	public class AbstractRWDictionaryContainer implements IRWContainer
	{


		protected var dict:Dictionary;


		protected var _size:int = 0;



		public function get size():uint
		{
			return _size;
		}


		public function get isEmpty():Boolean
		{
			return _size == 0;
		}

		
		// dummy
		// TODO: find a better solution for this
		private var _autoUpdateFlag:AutoUpdateFlag = new AutoUpdateFlag( );
		public function get autoUpdateFlag():AutoUpdateFlag
		{
			return _autoUpdateFlag;
		}




		/**
		 * 
		 * 
		 * 
		 * @param maxMultiplicity
		 * 
		 */
		public function AbstractRWDictionaryContainer( )
		{
		
			dict = new Dictionary( );
		
		}



		protected function m( e:*, delta:int = 0 ):uint
		{
		
			var multiplicity:int;

			if ( dict[ e ] === undefined )
				multiplicity = 0;
			else
				multiplicity = uint( dict[ e ] );
			
			if ( delta == 0 )
				return multiplicity;
			
			multiplicity += delta;
			
			// add to the internal dictionary
			dict[ e ] = multiplicity;
			// increase size
			_size += delta;
			
			
			return multiplicity;															
		
		}



		
		public function clear():void
		{
			dict = new Dictionary( );
			_size = 0;
		}
		
		
		
		public function contains( e:* ):Boolean
		{
			if ( dict[ e ] === undefined )
				return false;
			return true;
		}
		
		
		
		public function any( emptyValue:* = undefined ):*
		{
			for ( var e:* in dict )
				return e;
			return emptyValue;
		}


	
		

		
		
		
		
		
		public function getMultiplicity( e:* ):uint
		{
			return m( e );
		}
		
		
		
		public function remove( e:* ):void
		{

			_size -= m( e );
			delete dict[ e ];			

		}
		



		public function walk( walker:Function ):void
		{
			
			for ( var e:* in dict )
			{
				
				var res:* = walker.apply( null, [ e, uint( dict[ e ] ) ] );	
				
				if ( res === true ) // if the walker returns true, we stop
				{
					break;
				}
			
			}
			
		}
		
		
		
		
		public function compare( other:* ):ComparisonResult
		{
			return ContainerUtil.doCompare( this, other );
		}
		


//		public function toArray( ):Array
//		{
//			return ContainerUtil.toArray( this );
//		}
		
		
		public function get asArray( ):Array
		{
			return ContainerUtil.toArray( this );
		}



		public function toString( ):String
		{
			return asArray.join(",");
		}

		
		

	}

}